package com.joey.cloud.annotation.log;

import com.alibaba.fastjson.JSONObject;
import com.joey.cloud.communal.constant.BaseConstant;
import com.joey.cloud.communal.entity.LogTrace;
import com.joey.cloud.communal.utils.JoeDevUtils;
import com.joey.cloud.communal.utils.JwtUtils;
import com.joey.cloud.communal.utils.ResponseUtil;
import com.joey.cloud.provider.cache.CacheFeignService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.LocalDateTime;

/**
 * 日志注解实现
 * @author joey
 */
@Component
@Aspect
@Slf4j
public class JoeLogAspect {
    @Resource
    CacheFeignService cacheFeignService;

    @Pointcut("@annotation(com.joey.cloud.annotation.log.JoeLog) " +
            "|| execution(public * com.joey.cloud..*Controller.*(..))")
    public void handle() {}

    @Around("handle()")
    public Object action(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature signature = (MethodSignature)joinPoint.getSignature();
        JoeLogIgnore annotation = signature.getMethod().getAnnotation(JoeLogIgnore.class);
        //是否有忽略注解
        if(annotation!=null){
            return joinPoint.proceed();
        }
        ResponseUtil<String> res = cacheFeignService.redisStrGet("joeLogEnable");
        //是否开启日志追踪
        if(res!=null&&res.getSuccess()&& BaseConstant.TRUE_STR.equals(res.getData())){
            LogTrace traceLog = new LogTrace();
            Object result = null;
            LocalDateTime now = LocalDateTime.now();
            long startTime = System.currentTimeMillis();
            try {
                result = joinPoint.proceed();
            }catch (Throwable e){
                traceLog.setException(JoeDevUtils.limitStr(e,1000));
                throw new Throwable(e);
            }finally {
                long endTime = System.currentTimeMillis();
                traceLog.setTraceId(JwtUtils.getTraceId());
                traceLog.setDuration(endTime-startTime);
                traceLog.setClassName(JoeDevUtils.limitStr(signature.getDeclaringType().getName(),120));
                traceLog.setMethodName(JoeDevUtils.limitStr(signature.getName(),30));
                traceLog.setParamContent(JoeDevUtils.limitStr(joinPoint.getArgs(),1000));
                traceLog.setResultContent(JoeDevUtils.limitStr(result,1000));
                traceLog.setCreateBy(JwtUtils.getCurrentUserIdNoException());
                traceLog.setUrl(JoeDevUtils.getRequestURI());
                traceLog.setCreateTime(now);
                cacheFeignService.redisLeftPush("traceLogList",JSONObject.toJSONString(traceLog));
            }
            return result;
        }else {
            return joinPoint.proceed();
        }
    }
}
